package controllcivil.abstracts;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import controllcivil.bean.Entity;
import controllcivil.excecao.ExceptionCRUD;
import controllcivil.interfaces.IGeneric;

public abstract class AbstractEBJ<T extends Entity> implements IGeneric<T>{

	@PersistenceContext(unitName = "ControllCivil_Persistence")
	protected EntityManager em;
	
	/*
	 * (non-Javadoc)
	 * @see controllcivil.interfaces.IGeneric#salvar(java.lang.Object)
	 */
	@Override
	public void salvar(T entity) throws ExceptionCRUD{
		
		try{
			if (entity.isNewData()) {
				em.persist(entity);
			} else {
				em.merge(entity);
			}
		}catch (PersistenceException e) {
			this.rooback();
			throw new ExceptionCRUD (e.getMessage());
		}		
		
	}
	
	/*
	 * (non-Javadoc)
	 * @see controllcivil.interfaces.IGeneric#salvar(java.util.List)
	 */
	@Override
	public void salvar(List<T> listaEntity) throws ExceptionCRUD{
		for (T entity : listaEntity) {
			salvar(entity);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see controllcivil.interfaces.IGeneric#deletar(java.lang.Object)
	 */
	@Override
	public void deletar (T entity) throws ExceptionCRUD{		
		
		if (entity.getId() == 0){
			throw new ExceptionCRUD("MSG_SUCCESS_ITEM_NAO_ENCONTRADO_PARAMETRO", new String[]{entity.getClass().getSimpleName() + " "  + entity.getId()});
		}
		
		try {		
			
			em.remove(em.contains(entity) ? entity : em.merge(entity));
			
		} catch (PersistenceException e) {
			this.rooback();
			throw new ExceptionCRUD(e.getMessage());
			
		}
		
	}
	
	/*
	 * (non-Javadoc)
	 * @see controllcivil.interfaces.IGeneric#pesquisarPorID(java.lang.Object)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public T pesquisarPorID(T entity){
		return (T) em.find(entity.getClass(), entity.getId());
	}
	
	/*
	 * (non-Javadoc)
	 * @see controllcivil.interfaces.IGeneric#pesquisaPorParametros(java.lang.StringBuilder, java.util.Map)
	 */
	@Override
	public List<T> pesquisaPorParametros(StringBuilder hql, Map<String, Object> parametros){
		return pesquisaPorParametros(hql, parametros, 0);
		
	}
	
	/*
	 * (non-Javadoc)
	 * @see controllcivil.interfaces.IGeneric#pesquisaPorParametros(java.lang.StringBuilder, java.util.Map, int)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<T> pesquisaPorParametros(StringBuilder hql, Map<String, Object> parametros, int totalResultado){
		
		List<T> retorno = new ArrayList<T>();
		Query query = em.createQuery(hql.toString());
		
		if(parametros != null && parametros.size() > 0){
			for (Map.Entry<String, Object> parametro : parametros.entrySet()) {  
				
			    String key = parametro.getKey();  
			    query.setParameter(key, parametro.getValue());		 
	
			}  
		}
		
		if (totalResultado == TODOS_RESULTADOS_INT){
			retorno = query.getResultList();
			
		}else{
			query.setMaxResults(totalResultado);
			retorno = query.getResultList();
		}		
		
		return retorno;
	}
	
	/*
	 * (non-Javadoc)
	 * @see controllcivil.interfaces.IGeneric#rooback()
	 */
	@Override
	public void rooback(){
		this.em.getTransaction().rollback();
	}
	
	
	
	
}
